function ModelCreator(Model) {
  class ExtendModel extends Model {
    constructor(...args) {
      super(...args)
    }

    static call_button_after(name, action_info) {
      if (name === 'action_register_payment') {
        return {
          ...action_info,
          xml_id: 'account_wizard.action_payment_register_wizard'
        }
      } else {
        // alert(`todo, ${name}`)
        // throw 'error'
      }
    }

    static async sale_order_get(ids, kw = {}) {
      const get_line_ids = async () => {
        const { record = {} } = kw
        if ('line_ids' in record) {
          return record.line_ids
        } else {
          const rec = await this.read_one(ids, ['line_ids'])
          return rec.line_ids
        }
      }
      const line_ids = await get_line_ids()
      const lines = await this.env
        .model('account.move.line')
        .read(line_ids, ['sale_line_ids'])

      const sale_line_ids = lines.reduce((acc, line) => {
        acc = [...acc, ...line.sale_line_ids]
        return acc
      }, [])

      const so_lines = await this.env
        .model('sale.order.line')
        .read(sale_line_ids, ['order_id'])

      const so_ids = Object.values(
        await so_lines.reduce((acc, line) => {
          acc[line.order_id[0]] = {
            id: line.order_id[0],
            name: line.order_id[1]
          }
          return acc
        }, {})
      )
      return so_ids
    }

    static async purchase_order_get(ids, kw = {}) {
      const get_line_ids = async () => {
        const { record = {} } = kw
        if ('line_ids' in record) {
          return record.line_ids
        } else {
          const rec = await this.read_one(ids, ['line_ids'])
          return rec.line_ids
        }
      }
      const line_ids = await get_line_ids()
      const lines = await this.env
        .model('account.move.line')
        .read(line_ids, ['purchase_line_id'])

      const sale_line_ids = lines.reduce((acc, line) => {
        if (line.purchase_line_id) {
          acc.push(line.purchase_line_id[0])
        }
        return acc
      }, [])

      const so_lines = await this.env
        .model('purchase.order.line')
        .read(sale_line_ids, ['order_id'])

      const so_ids = Object.values(
        await so_lines.reduce((acc, line) => {
          acc[line.order_id[0]] = {
            id: line.order_id[0],
            name: line.order_id[1]
          }
          return acc
        }, {})
      )
      return so_ids
    }

    static async paymemt_get(ids, kw = {}) {
      const get_invoice_payments_widget = async () => {
        const { record = {} } = kw
        if ('invoice_payments_widget' in record) {
          return record.invoice_payments_widget
        } else {
          const rec = await this.read_one(ids, ['invoice_payments_widget'])
          return rec.invoice_payments_widget
        }
      }
      const payments_widget = await get_invoice_payments_widget()

      const { content = [] } = payments_widget || {}

      const pyements = content.map(item => {
        return {
          ...item
        }
      })

      return pyements
    }
  }
  return ExtendModel
}

const AddonsModels = {
  'account.move': ModelCreator
}

export default AddonsModels
